package org.uim.cricket.storage;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;

import org.uim.cricket.entities.MatchPlayer;
import org.uim.cricket.entities.Official;
import org.uim.cricket.entities.Player;
import org.uim.cricket.entities.batting.BattingInning;
import org.uim.cricket.entities.match.CricketMatch;
import org.uim.cricket.entities.match.MatchOfficials;
import org.uim.cricket.storage.raise.CheckForCountry;
import org.uim.cricket.storage.raise.CheckForGround;
import org.uim.cricket.storage.raise.CheckForOfficial;
import org.uim.cricket.storage.raise.CheckForPlayer;
import org.uim.cricket.storage.raise.CheckForSeries;

public class PreProtocolDBExecutor {

	private Storage storage = null;
	
	public PreProtocolDBExecutor(Storage theStorage) {
		this.storage = theStorage;
	}
	
	public StringBuilder execute() throws Exception {
		CricketMatch match = storage.getMatch();
		StringBuilder query = new StringBuilder();
		
		StringBuilder res = null;
		res = this.checkForCountries(match);
		if (res != null) {
			query.append(res.toString());
		}
		
		
		if (match.getGround() != null) {
			String sres = new CheckForGround().raiseGround(match, match.getGround());
			if (sres != null) query.append(sres);
		}
		
		if (match.getSeries() != null) {
			String sres = new CheckForSeries().raiseSeries(match, match.getSeries());
			if (sres != null) query.append(sres);
		}
		
		res = this.checkForPlayers();
		if (res != null) query.append(res.toString());
		
		return query;
		
	}
	
	private StringBuilder checkForPlayers() throws Exception {
		HashMap<String, Player> plays = new HashMap<String, Player>();
		HashMap<String, Official> offs = new HashMap<String, Official>();
		
		if (this.storage.getPlayers() != null) {
			
			for (String team : this.storage.getPlayers().keySet()) {
				List<MatchPlayer> ps = this.storage.getPlayers().get(team);
				
				for (int i=0; i<ps.size(); i++) {
					MatchPlayer mp = ps.get(i);
					if (mp == null) continue;
					
					if (mp.getPlayer() != null && !plays.containsKey(mp.getPlayer().getId())) {
						plays.put(mp.getPlayer().getId(), mp.getPlayer());
					}
				}
			}
				
			for (String team : this.storage.getPlayers().keySet()) {
				List<MatchPlayer> ps = this.storage.getPlayers().get(team);
				
				for (int i=0; i<ps.size(); i++) {
					MatchPlayer mp = ps.get(i);
					if (mp == null) continue;
					if (mp.getBattingInnings() != null) {
						for (int b=0; b<mp.getBattingInnings().size(); b++) {
							
							BattingInning bi = mp.getBattingInnings().get(b);
							if (bi == null) continue;
							if (bi.getOutDetails() != null && bi.getOutDetails().getFielders() != null) {
								for (int f=0; f<bi.getOutDetails().getFielders().length; f++) {
									if (bi.getOutDetails().getFielders()[f] != null &&
											!plays.containsKey(bi.getOutDetails().getFielders()[f].getId())) {
										plays.put(bi.getOutDetails().getFielders()[f].getId(), bi.getOutDetails().getFielders()[f]);
									}
								}	
							}
							
						}
					}
				}
				
			}
			
			
		}
		
		if (this.storage.getMatch() != null) {
			if (this.storage.getMatch().getOfficials() != null) {
				MatchOfficials moff = this.storage.getMatch().getOfficials();
				if (moff.getReferee() != null && moff.getReferee().getId() != null 
						&& !offs.containsKey(moff.getReferee().getId())) {
					offs.put(moff.getReferee().getId(), moff.getReferee());
				}
				if (moff.getReservedUmpire() != null && moff.getReservedUmpire().getId() != null
						&& !offs.containsKey(moff.getReservedUmpire().getId())) {
					offs.put(moff.getReservedUmpire().getId(), moff.getReservedUmpire());
				}
				if (moff.getTvUmpire() != null && moff.getTvUmpire().getId() != null 
						&& !offs.containsKey(moff.getTvUmpire().getId())) {
					offs.put(moff.getTvUmpire().getId(), moff.getTvUmpire());
				}
				if (moff.getUmpires() != null) {
					for (int i=0; i<moff.getUmpires().length; i++) {
						if (moff.getUmpires()[i] != null && moff.getUmpires()[i].getId() != null 
								&& !offs.containsKey(moff.getUmpires()[i].getId())) {
							offs.put(moff.getUmpires()[i].getId(), moff.getUmpires()[i]);
						}
					}
				}
			}
		}
		
		StringBuilder query = new StringBuilder();
		for (String pid : plays.keySet()) {
			if (pid.equalsIgnoreCase("null")) continue;
			query.append(new CheckForPlayer().raisePlayer(this.storage.getMatch(), plays.get(pid)));
		}
		for (String pid : offs.keySet()) {
			if (pid.equalsIgnoreCase("null")) continue;
			query.append(new CheckForOfficial().raiseOfficial(this.storage.getMatch(), offs.get(pid)));
		}
		return query;
	}
	
	
	private StringBuilder checkForCountries(CricketMatch match) throws Exception {
		HashSet<String> teams = new HashSet<String>();
		
		if (match != null) {
			if (match.getTeam1() != null) teams.add(match.getTeam1());
			if (match.getTeam2() != null) teams.add(match.getTeam2());
			
			if (match.getOfficials() != null) {
				MatchOfficials moff = match.getOfficials();
				if (moff.getReferee() != null && moff.getReferee().getCountry() != null) {
					teams.add(moff.getReferee().getCountry());
				}
				if (moff.getReservedUmpire() != null && moff.getReservedUmpire().getCountry() != null) {
					teams.add(moff.getReservedUmpire().getCountry());
				}
				if (moff.getTvUmpire() != null && moff.getTvUmpire().getCountry() != null) {
					teams.add(moff.getTvUmpire().getCountry());
				}
				if (moff.getUmpires() != null) {
					for (int i=0; i<moff.getUmpires().length; i++) {
						if (moff.getUmpires()[i] != null && moff.getUmpires()[i].getCountry() != null) {
							teams.add(moff.getUmpires()[i].getCountry());
						}
					}
				}
			}
			
		}

		if (storage.getPlayers() != null) {
			for (String team : storage.getPlayers().keySet()) {
				teams.add(team);
			}
		}
		
		StringBuilder query = new StringBuilder();
		for (String team : teams) {
			if (team == null || team.length() == 0 || team.equalsIgnoreCase("null")) continue;
			query.append(new CheckForCountry().raiseCountry(team));
		}
		return query;
	}

	public void setStorage(Storage storage) {
		this.storage = storage;
	}
	
	public Storage getStorage() {
		return storage;
	}
	
}
